package management;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentLinkedQueue;

import event.AuctionEvent;
import event.BidEvent;
import event.Event;
import event.StatisticsEvent;
import event.UserEvent;

/**
 * Prints the received event informations.
 * 
 * @author Lukas
 *
 */
public class ClientEventReceiverImpl implements ClientEventReceiver {
	private boolean hide = true;
	private ConcurrentLinkedQueue<String> messageList = new ConcurrentLinkedQueue<String>();

	@Override
	public void processEvent(Event event) {
		if (hide) {
			messageList.add(message(event));
		} else {
			System.out.println(message(event));
		}
	}
	
	private String message(Event event) {
		StringBuilder sb = new StringBuilder();
		sb.append(event.getType());
		sb.append(": ");
		sb.append(new Date(event.getTimestamp()));
		sb.append(" - ");
		
		if (event instanceof AuctionEvent) {
			auctionMessage((AuctionEvent) event, sb);
		} else if (event instanceof UserEvent) {
			userMessage((UserEvent) event, sb);
		} else if (event instanceof BidEvent) {
			bidMessage((BidEvent) event, sb);
		} else if (event instanceof StatisticsEvent) {
			statisticsMessage((StatisticsEvent) event, sb);
		}
		
		return sb.toString();
	}
	
	private void auctionMessage(AuctionEvent event, StringBuilder sb) {
		if (event.getType().equals("AUCTION_STARTED")) {
			sb.append("an auction with id ");
			sb.append(event.getAuctionID());
			sb.append(" was created");
		} else if (event.getType().equals("AUCTION_ENDED")) {
			sb.append("auction ");
			sb.append(event.getAuctionID());
			sb.append(" ended");
		}
	}
	
	private void userMessage(UserEvent event, StringBuilder sb) {
		if (event.getType().equals("USER_LOGIN")) {
			sb.append("user ");
			sb.append(event.getUserName());
			sb.append(" logged in");
		} else if (event.getType().equals("USER_LOGOUT")) {
			sb.append("user ");
			sb.append(event.getUserName());
			sb.append(" logged out");
		} else if (event.getType().equals("USER_DISCONNECTED")) {
			sb.append("user ");
			sb.append(event.getUserName());
			sb.append(" has been disconnected");
		}
	}
	
	private void bidMessage(BidEvent event, StringBuilder sb) {
		if (event.getType().equals("BID_PLACED")) {
			sb.append("user ");
			sb.append(event.getUserName());
			sb.append(" placed bid ");
			sb.append(doubleToStrF(event.getPrice(), 2));
			sb.append(" on auction ");
			sb.append(event.getAuctionID());
		} else if (event.getType().equals("BID_OVERBID")) {
			sb.append("user ");
			sb.append(event.getUserName());
			sb.append(" overbid with ");
			sb.append(doubleToStrF(event.getPrice(), 2));
			sb.append(" on auction ");
			sb.append(event.getAuctionID());
		} else if (event.getType().equals("BID_WON")) {
			sb.append("user ");
			sb.append(event.getUserName());
			sb.append(" won auction ");
			sb.append(event.getAuctionID());
			sb.append(" with ");
			sb.append(doubleToStrF(event.getPrice(), 2));
		}
	}
	
	private void statisticsMessage(StatisticsEvent event, StringBuilder sb) {
		if (event.getType().equals("USER_SESSIONTIME_MIN")) {
			sb.append("minimum sessiontime is ");
			sb.append((int)(event.getValue() / 1000));
			sb.append(" seconds");
		} else if (event.getType().equals("USER_SESSIONTIME_MAX")) {
			sb.append("maximum sessiontime is ");
			sb.append((int)(event.getValue() / 1000));
			sb.append(" seconds");
		} else if (event.getType().equals("USER_SESSIONTIME_AVG")) {
			sb.append("average session time is ");
			sb.append((int)(event.getValue() / 1000));
			sb.append(" seconds");
		} else if (event.getType().equals("BID_PRICE_MAX")) {
			sb.append("maximum bid price seen so far is ");
			sb.append(doubleToStrF(event.getValue(), 2));
		} else if (event.getType().equals("BID_COUNT_PER_MINUTE")) {
			sb.append("current bids per minute is ");
			sb.append(doubleToStrF(event.getValue(), 3));
		} else if (event.getType().equals("AUCTION_TIME_AVG")) {
			sb.append("average auction time is ");
			sb.append((int)(event.getValue() / 1000));
		} else if (event.getType().equals("AUCTION_SUCCESS_RATIO")) {
			sb.append("current auction success ratio is ");
			sb.append(doubleToStrF(event.getValue(), 3));
		}
	}
	
	private String doubleToStrF(double d, int decimalPlaces) {
		StringBuilder pattern = new StringBuilder("0.");
		for (int i = 0; i < decimalPlaces; i++) {
			pattern.append('0');
		}
		DecimalFormat dec = new DecimalFormat(pattern.toString());
		return dec.format(d);
	}

	/**
	 * @param hide <tt>true</tt> if the messages should be stored, <tt>false</tt> if the
	 * messages should be printed immediately.
	 */
	public void setHide(boolean hide) {
		this.hide = hide;
	}
	
	/**
	 * Displays all queued messages to the user.
	 */
	public void print() {
		String s = messageList.poll();
		while (s != null) {
			System.out.println(s);
			s = messageList.poll();
		}
	}
}
